<template>
    <!-- 弹出层容器 -->
    <div v-show="shouldRender" class="fixed inset-0 z-[999] overflow-hidden sm:hidden" @click="handleMaskClick">
        <!-- 遮罩层 -->
        <div v-if="mask" class="absolute inset-0 bg-black/50 transition-opacity duration-300" :class="{
            'opacity-0': !isVisible,
            'opacity-100': isVisible
        }"></div>

        <!-- 内容容器 -->
        <div class="absolute transition-transform duration-300 ease-out" :class="[
            basePositionClasses,
            {
                'translate-y-full': direction === 'bottom' && !isVisible,
                '-translate-y-full': direction === 'top' && !isVisible,
                'translate-x-full': direction === 'right' && !isVisible,
                '-translate-x-full': direction === 'left' && !isVisible,
                'scale-95 opacity-0': direction === 'center' && !isVisible,
                'scale-100 opacity-100': direction === 'center' && isVisible
            }
        ]" :style="contentStyle" @click.stop>
            <!-- 插槽内容 -->
            <div class="bg-white dark:bg-[#181a20] shadow-lg w-full h-full overflow-auto">
                
                <slot></slot>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, watch, computed } from 'vue';

// 定义组件参数
const props = defineProps({
    // 控制显示/隐藏（v-model绑定）
    modelValue: {
        type: Boolean,
        default: false
    },
    // 弹出方向
    direction: {
        type: String,
        default: 'bottom',
        validator: (value) => ['top', 'bottom', 'left', 'right', 'center'].includes(value)
    },
    // 是否显示遮罩层
    mask: {
        type: Boolean,
        default: true
    },
    // 点击遮罩是否关闭
    maskClosable: {
        type: Boolean,
        default: true
    },
    // 弹出层宽度（左右方向有效）
    width: {
        type: [String, Number],
        default: '300px'
    },
    // 弹出层高度（上下方向有效）
    height: {
        type: [String, Number],
        default: ''
    },
    // 动画时长（毫秒）
    duration: {
        type: Number,
        default: 300
    },
    // 遮罩层透明度
    maskOpacity: {
        type: Number,
        default: 0.5
    }
});

// 定义事件
const emit = defineEmits(['update:modelValue', 'open', 'close', 'click-mask']);

// 状态管理
const isVisible = ref(props.modelValue);
const shouldRender = ref(props.modelValue); // 控制是否渲染DOM

// 监听显示状态变化
watch(
    () => props.modelValue,
    (newVal) => {
        if (newVal) {
            // 显示弹出层
            shouldRender.value = true;
            // 延迟触发动画，确保DOM已渲染
            setTimeout(() => {
                isVisible.value = true;
                emit('open');
                // 禁止背景滚动
                document.body.style.overflow = 'hidden';
            }, 10);
        } else {
            // 隐藏弹出层
            isVisible.value = false;
            emit('close');
            // 恢复背景滚动
            document.body.style.overflow = '';
            // 动画结束后销毁DOM
            setTimeout(() => {
                shouldRender.value = false;
            }, props.duration);
        }
    },
    { immediate: true }
);

// 点击遮罩层
const handleMaskClick = () => {
    emit('click-mask');
    if (props.maskClosable) {
        emit('update:modelValue', false);
    }
};

// 计算基础定位类
const basePositionClasses = computed(() => {
    switch (props.direction) {
        case 'top':
            return 'top-0 left-0 right-0';
        case 'bottom':
            return 'bottom-0 left-0 right-0';
        case 'left':
            return 'top-0 left-0 bottom-0';
        case 'right':
            return 'top-0 right-0 bottom-0';
        case 'center':
            return 'top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2';
        default:
            return 'bottom-0 left-0 right-0';
    }
});

// 计算内容样式
const contentStyle = computed(() => {
    const style = {};

    // 设置遮罩透明度
    if (props.mask) {
        style['--mask-opacity'] = props.maskOpacity;
    }

    // 根据方向设置尺寸
    switch (props.direction) {
        case 'top':
        case 'bottom':
            style.height = typeof props.height === 'number' ? `${props.height}px` : props.height;
            style.width = '100%';
            break;
        case 'left':
        case 'right':
            style.width = typeof props.width === 'number' ? `${props.width}px` : props.width;
            style.height = '100%';
            break;
        case 'center':
            // 居中方向可以不设置固定尺寸，由内容决定
            break;
    }

    // 设置动画时长
    style.transitionDuration = `${props.duration}ms`;

    return style;
});
</script>

<style scoped></style>
